package main

import (
	"fmt"
	"strconv"
)

type Node struct {
	item int
	next *Node
}

func (n *Node) String() string {
	var next string
	if n.next == nil {
		next = "null"
	} else {
		next = strconv.Itoa(n.next.item)
	}
	return fmt.Sprintf(
		"%d ==> %s",
		n.item,
		next,
	)
}

type LinkedList struct {
	head *Node
	tail *Node
	len  int
}

func New() *LinkedList {
	return &LinkedList{}
}

func (l *LinkedList) Len() int {
	return l.len
}

func (l *LinkedList) Append(item int) {
	node := new(Node)
	node.item = item

	if l.head == nil {
		l.head = node
		l.tail = node
	} else {
		l.tail.next = node
		l.tail = node
	}

	l.len++
}

func (l *LinkedList) IterNodes() {
	p := l.head
	for p != nil {
		fmt.Println(p)
		p = p.next
	}
}

func main() {
	ll := New()
	ll.Append(2)
	ll.Append(3)
	ll.Append(4)
	ll.Append(8)
	fmt.Println(ll, ll.len)
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

	ll.IterNodes()
}
